import axios from 'axios'
import { useOidcStore } from '@/stores/oidc'

export enum AuthMode {
  None = 'None',
  Bearer = 'Bearer'
}

export interface DefaultHttpActionResult {
  message: string
  isSuccess: boolean
}

export interface HttpActionResult<TResult> extends DefaultHttpActionResult {
  result: TResult | null
}

const oidcStore = useOidcStore()

function getDefaultFailedResult(message: string): DefaultHttpActionResult {
  return {
    isSuccess: false,
    message: message
  }
}

function getFailedResult<TResult>(message: string): HttpActionResult<TResult> {
  return {
    result: null,
    isSuccess: false,
    message: message
  }
}

function getQueryString(obj: any): string | null {
  if (obj == null) {
    return null
  }

  const params = new URLSearchParams()
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      params.append(key, obj[key])
    }
  }
  return params.toString()
}

export async function deleteByUrlAsync(
  url: string,
  authMode: AuthMode = AuthMode.None
): Promise<DefaultHttpActionResult> {
  if (authMode != AuthMode.None && !oidcStore.isLogin) {
    return getDefaultFailedResult('用户未登录！')
  }

  if (authMode == AuthMode.Bearer) {
    try {
      const result = await axios.delete(url, {
        headers: {
          Authorization: oidcStore.getBearerToken()
        }
      })

      if (result.status == 200) {
        return result.data as DefaultHttpActionResult
      } else {
        return getDefaultFailedResult('HTTP 请求失败,HTTP_CODE=' + result.status)
      }
    } catch (err) {
      console.error(err)
      return getDefaultFailedResult('HTTP 请求错误！')
    }
  } else {
    try {
      const result = await axios.delete(url)

      if (result.status == 200) {
        return result.data as DefaultHttpActionResult
      } else {
        return getDefaultFailedResult('HTTP 请求失败,HTTP_CODE=' + result.status)
      }
    } catch (err) {
      console.error(err)
      return getDefaultFailedResult('HTTP 请求错误！')
    }
  }
}

export async function deleteAsync(
  url: string,
  arg: string,
  authMode: AuthMode = AuthMode.None
): Promise<DefaultHttpActionResult> {
  if (authMode != AuthMode.None && !oidcStore.isLogin) {
    return getDefaultFailedResult('用户未登录！')
  }

  if (authMode == AuthMode.Bearer) {
    try {
      const result = await axios.delete(url + '/' + arg, {
        headers: {
          Authorization: oidcStore.getBearerToken()
        }
      })

      if (result.status == 200) {
        return result.data as DefaultHttpActionResult
      } else {
        return getDefaultFailedResult('HTTP 请求失败,HTTP_CODE=' + result.status)
      }
    } catch (err) {
      console.error(err)
      return getDefaultFailedResult('HTTP 请求错误！')
    }
  } else {
    try {
      const result = await axios.delete(url + '/' + arg)

      if (result.status == 200) {
        return result.data as DefaultHttpActionResult
      } else {
        return getDefaultFailedResult('HTTP 请求失败,HTTP_CODE=' + result.status)
      }
    } catch (err) {
      console.error(err)
      return getDefaultFailedResult('HTTP 请求错误！')
    }
  }
}

export async function getByUrlAsync<TResult>(
  fullUrl: string,
  authMode: AuthMode = AuthMode.None
): Promise<HttpActionResult<TResult>> {
  if (authMode != AuthMode.None && !oidcStore.isLogin) {
    return getFailedResult<TResult>('用户未登录！')
  }

  if (authMode == AuthMode.Bearer) {
    try {
      const result = await axios.get(fullUrl, {
        headers: {
          Authorization: oidcStore.getBearerToken()
        }
      })

      if (result.status == 200) {
        return result.data as HttpActionResult<TResult>
      } else {
        return getFailedResult('HTTP 请求失败,HTTP_CODE=' + result.status)
      }
    } catch (err) {
      console.error(err)
      return getFailedResult('HTTP 请求错误！')
    }
  } else {
    try {
      const result = await axios.get(fullUrl)

      if (result.status == 200) {
        return result.data as HttpActionResult<TResult>
      } else {
        return getFailedResult('HTTP 请求失败,HTTP_CODE=' + result.status)
      }
    } catch (err) {
      console.error(err)
      return getFailedResult('HTTP 请求错误！')
    }
  }
}

export async function getByObjectArgsAsync<TResult>(
  url: string,
  args: object | null = null,
  authMode: AuthMode = AuthMode.None
): Promise<HttpActionResult<TResult>> {
  if (authMode != AuthMode.None && !oidcStore.isLogin) {
    return getFailedResult<TResult>('用户未登录！')
  }

  const queryString = getQueryString(args) || ''

  if (authMode == AuthMode.Bearer) {
    try {
      const result = await axios.get(url + '?' + queryString, {
        headers: {
          Authorization: oidcStore.getBearerToken()
        }
      })

      if (result.status == 200) {
        return result.data as HttpActionResult<TResult>
      } else {
        return getFailedResult('HTTP 请求失败,HTTP_CODE=' + result.status)
      }
    } catch (err) {
      console.error(err)
      return getFailedResult('HTTP 请求错误！')
    }
  } else {
    try {
      const result = await axios.get(url + '?' + queryString)

      if (result.status == 200) {
        return result.data as HttpActionResult<TResult>
      } else {
        return getFailedResult('HTTP 请求失败,HTTP_CODE=' + result.status)
      }
    } catch (err) {
      console.error(err)
      return getFailedResult('HTTP 请求错误！')
    }
  }
}

export async function defaultPostAsync(
  url: string,
  data: object,
  authMode: AuthMode = AuthMode.None
): Promise<DefaultHttpActionResult> {
  if (authMode != AuthMode.None && !oidcStore.isLogin) {
    return getDefaultFailedResult('用户未登录！')
  }

  if (authMode == AuthMode.Bearer) {
    try {
      const result = await axios.post(url, data, {
        headers: {
          Authorization: oidcStore.getBearerToken()
        }
      })

      if (result.status == 200) {
        return result.data as DefaultHttpActionResult
      } else {
        return getDefaultFailedResult('HTTP 请求失败,HTTP_CODE=' + result.status)
      }
    } catch (err) {
      console.error(err)
      return getDefaultFailedResult('HTTP 请求错误！')
    }
  } else {
    try {
      const result = await axios.post(url, data)

      if (result.status == 200) {
        return result.data as DefaultHttpActionResult
      } else {
        return getDefaultFailedResult('HTTP 请求失败,HTTP_CODE=' + result.status)
      }
    } catch (err) {
      console.error(err)
      return getDefaultFailedResult('HTTP 请求错误！')
    }
  }
}

export async function postAsync<TResult>(
  url: string,
  data: object,
  authMode: AuthMode = AuthMode.None
): Promise<HttpActionResult<TResult>> {
  if (authMode != AuthMode.None && !oidcStore.isLogin) {
    return getFailedResult<TResult>('用户未登录！')
  }

  if (authMode == AuthMode.Bearer) {
    try {
      const result = await axios.post(url, data, {
        headers: {
          Authorization: oidcStore.getBearerToken()
        }
      })

      if (result.status == 200) {
        return result.data as HttpActionResult<TResult>
      } else {
        return getFailedResult('HTTP 请求失败,HTTP_CODE=' + result.status)
      }
    } catch (err) {
      console.error(err)
      return getFailedResult('HTTP 请求错误！')
    }
  } else {
    try {
      const result = await axios.post(url, data)

      if (result.status == 200) {
        return result.data as HttpActionResult<TResult>
      } else {
        return getFailedResult('HTTP 请求失败,HTTP_CODE=' + result.status)
      }
    } catch (err) {
      console.error(err)
      return getFailedResult('HTTP 请求错误！')
    }
  }
}

export async function patchByUrlAsync(url: string, authMode: AuthMode = AuthMode.None) {
  if (authMode != AuthMode.None && !oidcStore.isLogin) {
    return getDefaultFailedResult('用户未登录！')
  }

  if (authMode == AuthMode.Bearer) {
    try {
      const result = await axios.patch(url, {
        headers: {
          Authorization: oidcStore.getBearerToken()
        }
      })

      if (result.status == 200) {
        return result.data as DefaultHttpActionResult
      } else {
        return getDefaultFailedResult('HTTP 请求失败,HTTP_CODE=' + result.status)
      }
    } catch (err) {
      console.error(err)
      return getDefaultFailedResult('HTTP 请求错误！')
    }
  } else {
    try {
      const result = await axios.patch(url)

      if (result.status == 200) {
        return result.data as DefaultHttpActionResult
      } else {
        return getDefaultFailedResult('HTTP 请求失败,HTTP_CODE=' + result.status)
      }
    } catch (err) {
      console.error(err)
      return getDefaultFailedResult('HTTP 请求错误！')
    }
  }
}
